//****************************************************
// Porman Project 2
// Filename: CFramebufferObject.cpp
// Date: 2009/05/30
// Author: KengYu Lin
// Modify:
//****************************************************
#include "CGLDef.h"
#include "CTextureObject.h"
#include "CDepthStencilObject.h"
#include "CFramebufferObject.h"
#include "CAssert.h"

namespace Porman
{

namespace GL
{

//---------------------------------
// class CFramebufferObject::SData
//---------------------------------
CFramebufferObject::SData::SData() : 
m_pTex2D(NULL), 
m_pTex3D(NULL), 
m_pTexCube(NULL), 
m_pDS(NULL),   
m_iColorAttachment(0), 
m_iDepthAttachment(0), 
m_iStencilAttachment(0), 
m_iOffset(0), 
m_iLevel(0), 
m_eType(CTextureCubeObject::E_POSITIVE_X)
{
}

CFramebufferObject::SData::~SData()
{ 
     m_pTex2D = NULL; m_pTex3D = NULL; m_pTexCube = NULL; m_pDS = NULL;
}

void 
CFramebufferObject::SData::clear( void )
{
    m_pTex2D = NULL; m_pTex3D = NULL; m_pTexCube = NULL; m_pDS = NULL;
    m_iColorAttachment = m_iDepthAttachment = m_iStencilAttachment = m_iLevel = m_iOffset = 0;
    m_eType = CTextureCubeObject::E_POSITIVE_X;
}

int 
CFramebufferObject::SData::parse( int iIndex )
{
    switch( iIndex )
    {
    case 0:
        return GL_COLOR_ATTACHMENT0_EXT;
    case 1:
        return GL_COLOR_ATTACHMENT1_EXT;
    case 2:
        return GL_COLOR_ATTACHMENT2_EXT;
    case 3:
        return GL_COLOR_ATTACHMENT3_EXT;
    case 4:
        return GL_COLOR_ATTACHMENT4_EXT;
    case 5:
        return GL_COLOR_ATTACHMENT5_EXT;
    case 6:
        return GL_COLOR_ATTACHMENT6_EXT;
    default:
        return GL_COLOR_ATTACHMENT7_EXT;
    }
}

//---------------------------------
// class CFramebufferObject
//---------------------------------
CFramebufferObject::CFramebufferObject( CRenderDevice* pDevice ) :
CBaseObject(pDevice)
{ 
    setName("Non");
    m_iNumOfFrameBufferObj++; 
}

CFramebufferObject::~CFramebufferObject( void ) 
{ 
    m_iNumOfFrameBufferObj--; 
}

void 
CFramebufferObject::setRenderTarget2D( ERenderTargetAttachment enumAttachment, int iLevel, CTexture2DObject* pTextureObj )
{
    assert( pTextureObj );

    int iIndex = (int)enumAttachment;
    m_Datas[iIndex].clear();

    m_Datas[iIndex].m_iColorAttachment = m_Datas[iIndex].parse( iIndex );
    m_Datas[iIndex].m_iLevel = iLevel;
    m_Datas[iIndex].m_pTex2D = pTextureObj;
}

void 
CFramebufferObject::setRenderTarget3D( ERenderTargetAttachment enumAttachment, int iLevel, int iOffset, CTexture3DObject* pTextureObj )
{
    assert( pTextureObj );

    int iIndex = (int)enumAttachment;
    m_Datas[iIndex].clear();

    m_Datas[iIndex].m_iColorAttachment = m_Datas[iIndex].parse( iIndex );
    m_Datas[iIndex].m_iOffset = iOffset;
    m_Datas[iIndex].m_iLevel = iLevel;
    m_Datas[iIndex].m_pTex3D = pTextureObj;
}

void 
CFramebufferObject::setRenderTargetCube( ERenderTargetAttachment enumAttachment, CTextureCubeObject::ETexCubeFace enumType, int iLevel, CTextureCubeObject* pTextureObj )
{
    assert( pTextureObj );

    int iIndex = (int)enumAttachment;
    m_Datas[iIndex].clear();

    m_Datas[iIndex].m_iColorAttachment = m_Datas[iIndex].parse( iIndex );
    m_Datas[iIndex].m_eType = enumType;
    m_Datas[iIndex].m_iLevel = iLevel;
    m_Datas[iIndex].m_pTexCube = pTextureObj;
}

void 
CFramebufferObject::setDepthStencilTarget( CDepthStencilObject* pDepthStencilObj )
{
    assert( pDepthStencilObj );

    m_Datas[8].clear();

    m_Datas[8].m_iDepthAttachment = GL_DEPTH_ATTACHMENT_EXT;
    m_Datas[8].m_iStencilAttachment = GL_STENCIL_ATTACHMENT_EXT;
    m_Datas[8].m_pDS = pDepthStencilObj;
}

}//End namespace GL

}//End namespace Porman
